# agents/factor_agents/base_factor_agent.py
from abc import ABC, abstractmethod
from typing import Dict, List, Tuple, Optional
import numpy as np
from game_engine.game_state import FactorDevelopment, GameWorld

try:
    from utils.context_manager import ContextPriority
except ImportError:
    # 备用导入路径
    from context_manager import ContextPriority

class BaseFactorAgent(ABC):
    """因子智能体基类"""
    
    def __init__(self, factor: FactorDevelopment, game_world: GameWorld, strategy_manager=None, context_manager=None):
        self.factor = factor
        self.game_world = game_world
        self.strategy_manager = strategy_manager  # 添加策略管理器
        self.context_manager = context_manager  # 添加上下文管理器
        self.memory = []  # 记忆存储
        self.personality_traits = self._init_personality()
    
    def _init_personality(self) -> Dict[str, float]:
        """初始化性格特征"""
        return {
            "aggression": 0.5,      # 攻击性
            "caution": 0.5,         # 谨慎性  
            "social": 0.5,          # 社交性
            "exploration": 0.5,     # 探索性
            "training": 0.5         # 训练倾向
        }
    
    async def make_decision_with_context(self, current_time: int):
        """使用上下文的决策方法"""
        situation = self.evaluate_situation()
        
        # 存储当前状态到上下文
        if self.context_manager:
            await self.context_manager.store_context(
                component_name=self.factor.name,
                content=situation,
                priority=ContextPriority.MEDIUM,
                ttl_minutes=140  # 24小时
            )
        
        # 使用策略管理器进行决策
        decision_result = await self.strategy_manager.execute_decision(
            component_name=self.factor.factor_type.name.lower(),
            state=situation,
            decision_context={
                "current_time": current_time,
                "nearby_factors": [f.to_dict() for f in self.get_nearby_factors()],
                "memory": self.memory[-5:]  # 最近5个记忆
            }
        )
        
        return decision_result

    @abstractmethod
    def make_decision(self, current_time: int) -> str:
        """制定决策 - 子类必须实现"""
        pass
    
    @abstractmethod
    def evaluate_situation(self) -> Dict:
        """评估当前局势 - 子类必须实现"""
        pass
    
    def learn_from_experience(self, reward: float, new_state: Dict):
        """从经验中学习"""
        experience = {
            "state": self.evaluate_situation(),
            "action": self.last_action,
            "reward": reward,
            "new_state": new_state
        }
        self.memory.append(experience)
        
        # 限制记忆大小
        if len(self.memory) > 1000:
            self.memory.pop(0)
    
    def get_nearby_factors(self, radius: float = 20.0) -> List[FactorDevelopment]:
        """获取附近因子"""
        nearby = []
        for factor in self.game_world.factors:
            if (factor != self.factor and factor.is_alive and
                self._calculate_distance(self.factor.current_location, factor.current_location) <= radius):
                nearby.append(factor)
        return nearby
    
    def _calculate_distance(self, pos1: Tuple[float, float], pos2: Tuple[float, float]) -> float:
        """计算两点距离"""
        return np.sqrt((pos1[0] - pos2[0])**2 + (pos1[1] - pos2[1])**2)
    
    def should_use_special_ability(self) -> bool:
        """判断是否应该使用特殊能力"""
        # 基础逻辑：在危急情况或关键战斗中使用
        if self.factor.attributes['health'] < self.factor.attributes['health'] * 0.3:
            return True
        
        nearby_enemies = [f for f in self.get_nearby_factors() if self._is_potential_threat(f)]
        if len(nearby_enemies) >= 3:
            return True
            
        return False
    
    def _is_potential_threat(self, other_factor: FactorDevelopment) -> bool:
        """判断是否为潜在威胁"""
        # 简单实现：攻击性高的因子视为威胁
        return other_factor.attributes['attack'] > self.factor.attributes['defense']
